HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>2048 Game</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            background-color: #faf8ef;
            margin: 0;
            padding: ;
        }
        <demo>section
        h1 {
            font-size: 40px;
            margin: 0;
            color: #776e65;
        }
        
        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            width: 450px;
            margin: 0 auto 20px;
        }
        
        .score-container {
            background: #bbada0;
            padding: 5px 15px;
            border-radius: 5px;
            color: white;
            font-weight: bold;
            text-align: center;
        }
        
        .score-title {
            font-size: 13px;
        }
        
        .score-value {
            font-size: 25px;
        }
        
        .game-container {
            width: 450px;
            height: 450px;
            padding: 15px;
            background-color: #bbada0;
            border-radius: 6px;
            margin: 0 auto;
            position: relative;
        }
        
        .grid-container {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-gap: 15px;
            width: 100%;
            height: 100%;
        }
        
        .grid-cell {
            background-color: #cdc1b4;
            border-radius: 5px;
        }
        
        .tile {
            width: 100%;
            height: 100%;
            border-radius: 5px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 35px;
            font-weight: bold;
            color: #776e65;
            position: absolute;
            transition: all 0.1s ease-in-out;
        }
        
        .tile-2 { background-color: #eee4da; }
        .tile-4 { background-color: #ede0c8; }
        .tile-8 { background-color: #f2b179; color: white; }
        .tile-16 { background-color: #f59563; color: white; }
        .tile-32 { background-color: #f67c5f; color: white; }
        .tile-64 { background-color: #f65e3b; color: white; }
        .tile-128 { background-color: #edcf72; color: white; font-size: 30px; }
        .tile-256 { background-color: #edcc61; color: white; font-size: 30px; }
        .tile-512 { background-color: #edc850; color: white; font-size: 30px; }
        .tile-1024 { background-color: #edc53f; color: white; font-size: 25px; }
        .tile-2048 { background-color: #edc22e; color: white; font-size: 25px; }
        
        .game-over {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(238, 228, 218, 0.73);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            border-radius: 6px;
            z-index: 100;
            display: none;
        }
        
        .game-over-text {
            font-size: 60px;
            font-weight: bold;
            color: #776e65;
            margin-bottom: 30px;
        }
        
        .restart-button {
            background-color: #8f7a66;
            color: white;
            border: none;
            border-radius: 5px;
            padding: 10px 20px;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
        }
        
        .restart-button:hover {
            background-color: #9f8b77;
        }
        
        .instructions {
            width: 450px;
            margin: 20px auto 0;
            color: #776e65;
            text-align: left;
            line-height: 1.5;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>2048</h1>
        <div class="score-container">
            <div class="score-title">SCORE</div>
            <div class="score-value" id="score">0</div>
        </div>
    </div>
    
    <div class="game-container">
        <div class="grid-container" id="grid-container">
            <!-- 4x4 grid will be generated by JavaScript -->
        </div>
        
        <div class="game-over" id="game-over">
            <div class="game-over-text">Game Over!</div>
            <button class="restart-button" onclick="startGame()">Try Again</button>
        </div>
    </div>
    
    <div class="instructions">
        <p><strong>HOW TO PLAY:</strong> Use your arrow keys to move the tiles. When two tiles with the same number touch, they merge into one!</p>
    </div>
    
    <script>
        // Game variables
        let grid = [];
        let score = 0;
        let gameOver = false;
        const size = 4;
        
        // Initialize the game
        function initGame() {
            // Create grid
            const gridContainer = document.getElementById('grid-container');
            gridContainer.innerHTML = '';
            
            for (let i = 0; i < size; i++) {
                grid[i] = [];
                for (let j = 0; j < size; j++) {
                    grid[i][j] = 0;
                    
                    // Create grid cells
                    const cell = document.createElement('div');
                    cell.className = 'grid-cell';
                    gridContainer.appendChild(cell);
                }
            }
            
            // Add initial tiles
            addRandomTile();
            addRandomTile();
            
            // Update the display
            updateView();
        }
        
        // Start a new game
        function startGame() {
            score = 0;
            gameOver = false;
            document.getElementById('score').textContent = score;
            document.getElementById('game-over').style.display = 'none';
            initGame();
        }
        
        // Add a random tile (2 or 4) to an empty cell
        function addRandomTile() {
            const emptyCells = [];
            
            // Find all empty cells
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (grid[i][j] === 0) {
                        emptyCells.push({i, j});
                    }
                }
            }
            
            // If there are empty cells, add a new tile
            if (emptyCells.length > 0) {
                const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                grid[randomCell.i][randomCell.j] = Math.random() < 0.9 ? 2 : 4;
            }
        }
        
        // Update the view based on the grid
        function updateView() {
            // Remove all existing tiles
            document.querySelectorAll('.tile').forEach(tile => tile.remove());
            
            const gameContainer = document.querySelector('.game-container');
            const cellSize = (gameContainer.offsetWidth - 30) / size;
            
            // Add tiles for each cell with a value
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (grid[i][j] !== 0) {
                        const tile = document.createElement('div');
                        tile.className = `tile tile-${grid[i][j]}`;
                        tile.textContent = grid[i][j];
                        
                        // Position the tile
                        tile.style.width = `${cellSize - 10}px`;
                        tile.style.height = `${cellSize - 10}px`;
                        tile.style.top = `${15 + i * (cellSize + 5)}px`;
                        tile.style.left = `${15 + j * (cellSize + 5)}px`;
                        
                        gameContainer.appendChild(tile);
                    }
                }
            }
            
            // Update score
            document.getElementById('score').textContent = score;
        }
        
        // Check if the game is over
        function checkGameOver() {
            // Check if there are any empty cells
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (grid[i][j] === 0) {
                        return false;
                    }
                }
            }
            
            // Check if any adjacent tiles can be merged
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (j < size - 1 && grid[i][j] === grid[i][j + 1]) {
                        return false;
                    }
                    if (i < size - 1 && grid[i][j] === grid[i + 1][j]) {
                        return false;
                    }
                }
            }
            
            return true;
        }
        
        // Move tiles in the specified direction
        function move(direction) {
            if (gameOver) return;
            
            let moved = false;
            const oldGrid = JSON.parse(JSON.stringify(grid));
            
            // Process movement based on direction
            switch (direction) {
                case 'up':
                    for (let j = 0; j < size; j++) {
                        for (let i = 1; i < size; i++) {
                            if (grid[i][j] !== 0) {
                                let k = i;
                                while (k > 0 && grid[k - 1][j] === 0) {
                                    grid[k - 1][j] = grid[k][j];
                                    grid[k][j] = 0;
                                    k--;
                                    moved = true;
                                }
                                
                                if (k > 0 && grid[k - 1][j] === grid[k][j]) {
                                    grid[k - 1][j] *= 2;
                                    score += grid[k - 1][j];
                                    grid[k][j] = 0;
                                    moved = true;
                                }
                            }
                        }
                    }
                    break;
                    
                case 'down':
                    for (let j = 0; j < size; j++) {
                        for (let i = size - 2; i >= 0; i--) {
                            if (grid[i][j] !== 0) {
                                let k = i;
                                while (k < size - 1 && grid[k + 1][j] === 0) {
                                    grid[k + 1][j] = grid[k][j];
                                    grid[k][j] = 0;
                                    k++;
                                    moved = true;
                                }
                                
                                if (k < size - 1 && grid[k + 1][j] === grid[k][j]) {
                                    grid[k + 1][j] *= 2;
                                    score += grid[k + 1][j];
                                    grid[k][j] = 0;
                                    moved = true;
                                }
                            }
                        }
                    }
                    break;
                    
                case 'left':
                    for (let i = 0; i < size; i++) {
                        for (let j = 1; j < size; j++) {
                            if (grid[i][j] !== 0) {
                                let k = j;
                                while (k > 0 && grid[i][k - 1] === 0) {
                                    grid[i][k - 1] = grid[i][k];
                                    grid[i][k] = 0;
                                    k--;
                                    moved = true;
                                }
                                
                                if (k > 0 && grid[i][k - 1] === grid[i][k]) {
                                    grid[i][k - 1] *= 2;
                                    score += grid[i][k - 1];
                                    grid[i][k] = 0;
                                    moved = true;
                                }
                            }
                        }
                    }
                    break;
                    
                case 'right':
                    for (let i = 0; i < size; i++) {
                        for (let j = size - 2; j >= 0; j--) {
                            if (grid[i][j] !== 0) {
                                let k = j;
                                while (k < size - 1 && grid[i][k + 1] === 0) {
                                    grid[i][k + 1] = grid[i][k];
                                    grid[i][k] = 0;
                                    k++;
                                    moved = true;
                                }
                                
                                if (k < size - 1 && grid[i][k + 1] === grid[i][k]) {
                                    grid[i][k + 1] *= 2;
                                    score += grid[i][k + 1];
                                    grid[i][k] = 0;
                                    moved = true;
                                }
                            }
                        }
                    }
                    break;
            }
            
            // If the grid changed, add a new tile and update the view
            if (moved) {
                addRandomTile();
                updateView();
                
                // Check if game is over
                if (checkGameOver()) {
                    gameOver = true;
                    document.getElementById('game-over').style.display = 'flex';
                }
            }
        }
        
        // Keyboard event listener
        document.addEventListener('keydown', function(event) {
            switch (event.key) {
                case 'ArrowUp':
                    move('up');
                    break;
                case 'ArrowDown':
                    move('down');
                    break;
                case 'ArrowLeft':
                    move('left');
                    break;
                case 'ArrowRight':
                    move('right');
                    break;
            }
        });
        
        // Touch event handling for mobile devices
        let touchStartX = 0;
        let touchStartY = 0;
        let touchEndX = 0;
        let touchEndY = 0;
        
        document.addEventListener('touchstart', function(event) {
            touchStartX = event.touches[0].clientX;
            touchStartY = event.touches[0].clientY;
        }, false);
        
        document.addEventListener('touchend', function(event) {
            touchEndX = event.changedTouches[0].clientX;
            touchEndY = event.changedTouches[0].clientY;
            handleSwipe();
        }, false);
        
        function handleSwipe() {
            const dx = touchEndX - touchStartX;
            const dy = touchEndY - touchStartY;
            
            if (Math.abs(dx) > Math.abs(dy)) {
                if (dx > 0) {
                    move('right');
                } else {
                    move('left');
                }
            } else {
                if (dy > 0) {
                    move('down');
                } else {
                    move('up');
                }
            }
        }
        
        // Start the game when the page loads
        window.onload = startGame;
    </script>
</body>
</html>